﻿#ifndef BOARD_H
#define BOARD_H

/*! \class Board
 *  \brief     Classe do tipo \c Board.
 *  \details   Esta classe herda as propriedades da classe \c QGraphicsScene.
 *             Ela gerencia os eventos que
 *             acontecem na tela principal do jogo.
 *  \author    Ghybson
 *  \author    Luís
 *  \author    Willian
 *  \version   0.1
 *  \date      2011
 *  \copyright GNU Public License.
 *  \todo      Não está aparecendo documentando no doxygen os membros privados.
 *  \todo      Testar os indices de acesso \a Board::m_Map para impedir violação de acesso a memória.
 */

#include <QList>
#include <QGraphicsView>
#include <cstdlib>
#include <ctime>
#include "piece.h"
#include "level.h"
#include <QDebug>

class Board: public QGraphicsScene
{
public:       
    /*! \fn  Board()
     *  \brief  Construtor padrão classe \c Board.
     */
    Board();
    /*! \fn  ~Board()
     *  \brief  Destrutor padrão classe \c Board.
     */
    ~Board();
    /*! \fn  int getScore()
     *  \brief  Função membro pública da classe \c Board para obter a pontuação total.
     *  \return Retorna \a m_Score.
     */
    int getScore() const {return m_Score;}
    /*! \fn  Level getLevel()
     *  \brief  Função membro pública da classe \c Board para obter um objeto do tipo \c Level que contém as informações do level atual.
     *  \return Retorna o membro do tipo \c Level \a m_Level.
     */
    Level getLevel() const {return m_Level;}
    /*! \fn  QGraphicsScene* getNextPieceScene()
     *  \brief  Função membro pública da classe \c Board para obter um ponteiro para um \c QGraphicsScene que conterá o desenho de \a m_NextPiece.
     *  \return Retorna \a m_Score.
     */
    QGraphicsScene* getNextPieceScene() {return m_NextPieceScene;}
    /*! \fn  bool isGameOver()
     *  \brief  Função membro pública da classe \c Board para obter a situação do jogo.
     *  \return Retorna \a m_GameOver.
     */
    bool isGameOver() const {return m_GameOver;}
    /*! \fn  void setImageBackground()
     *  \brief  Função membro pública da classe \c Board para desenhar aleatóriamente uma imagem de fundo.
     */
    void setImageBackground();
    /*! \fn  void setImage(QImage img)
     *  \brief  Função membro pública da classe \c Board para escolher uma imagem de fundo.
     *  \param[in] img objeto do tipo \c QImage que contém a imagem de plano de fundo.
     *  \todo   Não funciona se não for passado o endereço completo das imagens.
     */
    void setImage(QImage img);
    /*! \fn  void redesenheBoard()
     *  \brief  Função membro pública da classe \c Board que através do mapeamento utilizado em \a m_Map redesenha as peças em suas novas posições com suas devidas cores.
     */
    void redesenheBoard();
    /*! \fn  void tryMoveRight()
     *  \brief  Função membro pública da classe \c Board que verifica se é possível realizar a movimentação de \a m_PecaAtual à direita.
     */
    void tryMoveRight();
    /*! \fn  void tryMoveLeft()
     *  \brief  Função membro pública da classe \c Board que verifica se é possível realizar a movimentação de \a m_PecaAtual à esquerda.
     */
    void tryMoveLeft();
    /*! \fn  void tryMoveDown()
     *  \brief  Função membro pública da classe \c Board que verifica se é possível realizar a movimentação de \a m_PecaAtual a baixo.
     */
    void tryMoveDown();
    /*! \fn  void tryRotation()
     *  \brief  Função membro pública da classe \c Board que verifica se é possível realizar a rotação de \a m_PecaAtual.
     */
    void tryRotation();
    /*! \fn  void randPiece()
     *  \brief  Função membro pública da classe \c Board que sorteia uma nova peça para ser adicionada ao tabuleiro.
     */
    void randPiece();
    /*! \fn  void clearData()
     *  \brief  Função membro pública da classe \c Board que limpa o tabuleiro e reinicia a pontuação e o level.
     */
    void clearData();
private:
    static const int s_maxX = 250, s_maxY = 350; /*!< Os valores de coordenadas maximas de X e Y */
    static const int s_VSqm = 14, s_HSqm = 10;   /*!< Quantidade de quadrados verticais e horizontais */
    int m_Score;                                 /*!< O valor inteiro de pontos do jogo */
    int m_NextPieceIndex;                        /*!< Inteiro sorteado que indica a próxima peça */
    bool m_GameOver;                             /*!< Boolean que indica se o jogo acabou */
    Piece *m_PecaAtual;                          /*!< Ponteiro para a peça atual para calcular movimentação */
    Piece *m_NextPiece;                          /*!< \a m_PecaAtual recebe este ponteiro no final de cada round */
    QGraphicsScene *m_NextPieceScene;            /*!< Ponteiro para um \c QGraphicsScene que mostra a próxima peça */
    QPair<bool,QColor> m_Map[s_VSqm][s_HSqm];    /*!< Par de dados que mapeia o board em quadrados */
    Level m_Level;                               /*!< Boolean que indica se o jogo acabou */

    /*! \fn  int randPieceIndex()
     *  \brief  Função membro privada da classe \c Board para sortear uma peça.
     *  \return Retorna um int de 0 a 5 para representar um tipo de peça.
     */
    int  randPieceIndex();
    /*! \fn  Piece* getRandPiece(int piece)
     *  \param[in] piece Inteiro que representa a peça a ser criada.
     *  \brief  Função membro privada da classe \c Board para obter a peça correspondente
     *          a um inteiro sorteado em \c int \fn randPieceIndex().
     *  \return Retorna um ponteiro de um tipo de peça representado pelo parâmetro piece.
     */
    Piece* getRandPiece(int piece);
    /*! \fn  bool checkLeftCollision(QList<QRect> &quads)
     *  @param[in] quads Lista de \c QRect que contém os quadrados que formam uma peça.
     *  \brief  Função membro privada da classe \c Board que verifica se haverá colisão de peças, ou com o limite da tela ao mover para a esquerda. 
     *  \return Retorna true caso a movimentação à esquerda resulte em uma colisão. Caso contrário, retorna false.
     */
    bool checkLeftCollision(QList<QRect> &quads);
    /*! \fn  bool checkRightCollision(QList<QRect> &quads)
     *  @param[in] quads Lista de \c QRect que contém os quadrados que formam uma peça.
     *  \brief  Função membro privada da classe \c Board que verifica se haverá colisão de peças, ou com o limite da tela ao mover para a direita.
     *  \return Retorna true caso a movimentação à direita resulte em uma colisão. Caso contrário, retorna false.
     */
    bool checkRightCollision(QList<QRect> &quads);
    /*! \fn  bool checkDownCollision(QList<QRect> &quads)
     *  @param[in] quads Lista de \c QRect que contém os quadrados que formam uma peça.
     *  \brief  Função membro privada da classe \c Board que verifica se haverá colisão de peças, ou com o limite da tela ao mover para baixo.
     *  \return Retorna true caso a movimentação para a baixo resulte em uma colisão. Caso contrário, retorna false.
     */
    bool checkDownCollision(QList<QRect> &quads);
    /*! \fn  bool checkOverlap(QList<QRect> &quads)
     *  @param[in] quads Lista de \c QRect que contém os quadrados que formam uma peça.
     *  \brief  Função membro privada da classe \c Board que verifica se haverá sobreposição de algum quadrado ao ocorrer a rotação da peça cujos quadrados estão em quads.
     *  \return Retorna true caso a rotação resulte em uma sobreposição de peças. Caso contrário, retorna false.
     */
    bool checkOverlap(QList<QRect> &quads);
    /*! \fn  void checkLinhasCompletas()
     *  \brief  Função membro privada da classe \c Board que verifica se alguma linha do tabuleiro está completa. Caso existam linhas completas, realiza uma chamada à função \fn tiraLinhaCompleta() e adiciona a devida pontuação.
     */
    void checkLinhasCompletas();
    /*! \fn  void checkBoardEmpty()
     *  \brief  Função membro privada da classe \c Board que verifica se o tabuleiro está vazio. Caso esteja, adiciona a devida pontuação.
     */
    void checkBoardEmpty();
    /*! \fn  void tiraLinhaCompleta()
     *  @param[in] linha Inteiro que indica qual linha deverá ser retirada do tabuleiro.
     *  \brief  Função membro privada da classe \c Board que retira todos os quadrados da linha recebida como parâmetro do atributo \a m_Map e move todas as peças acima 1 linha para baixo.
     */
    void tiraLinhaCompleta(int linha);
};

#endif // BOARD_H
